package jmine.tec.utils.collection;

import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import jmine.tec.utils.debug.impl.DebugRuntimeFactory;

/**
 * Classe que carrega arquivos .properties no classpath, inicializando um mapa com tais propriedades.
 * 
 * @author takeshi
 */
public class ClasspathPropertiesLoader implements Map<String, String> {

    private volatile Map<String, String> properties;

    private volatile boolean autoReload = DebugRuntimeFactory.ENABLED;

    /**
     * C'tor
     * 
     * @param resource o classpath resource
     * @throws IOException e
     */
    public ClasspathPropertiesLoader(String resource) throws IOException {
        Enumeration<URL> resources = this.getClass().getClassLoader().getResources(resource);
        Properties props = new Properties();
        while (resources.hasMoreElements()) {
            URL url = resources.nextElement();
            props.load(url.openStream());
        }
        Map<String, String> map = new HashMap<String, String>(props.size());
        Set<Entry<Object, Object>> entrySet = props.entrySet();
        for (Entry<Object, Object> entry : entrySet) {
            map.put(entry.getKey().toString(), entry.getValue().toString());
        }
        this.properties = map;
    }

    /**
     * 
     */
    private void verifyReload() {
        if (!this.autoReload) {
            return;
        }
        
    }

    /**
     * O mapa devolvido eh imutavel. Clientes devem copiar o mapa para poder modificar
     * 
     * @return the properties
     */
    public Map<String, String> getProperties() {
        return this;
    }

    /**
     * @see java.util.Map#clear()
     */
    public void clear() {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     */
    public boolean containsKey(Object key) {
        this.verifyReload();
        return this.properties.containsKey(key);
    }

    /**
     * {@inheritDoc}
     */
    public boolean containsValue(Object value) {
        this.verifyReload();
        return this.properties.containsValue(value);
    }

    /**
     * {@inheritDoc}
     */
    public Set<Entry<String, String>> entrySet() {
        this.verifyReload();
        return new HashSet<Entry<String, String>>(this.properties.entrySet());
    }

    /**
     * {@inheritDoc}
     */
    public String get(Object key) {
        this.verifyReload();
        return this.properties.get(key);
    }

    /**
     * {@inheritDoc}
     */
    public boolean isEmpty() {
        this.verifyReload();
        return this.properties.isEmpty();
    }

    /**
     * {@inheritDoc}
     */
    public Set<String> keySet() {
        this.verifyReload();
        return new HashSet<String>(this.properties.keySet());
    }

    /**
     * {@inheritDoc}
     */
    public String put(String key, String value) {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     */
    public void putAll(Map<? extends String, ? extends String> m) {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     */
    public String remove(Object key) {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     */
    public int size() {
        this.verifyReload();
        return this.properties.size();
    }

    /**
     * {@inheritDoc}
     */
    public Collection<String> values() {
        this.verifyReload();
        return new HashSet<String>(this.properties.values());
    }

    /**
     * @return the autoReload
     */
    public boolean isAutoReload() {
        return this.autoReload;
    }

    /**
     * @param autoReload the autoReload to set
     */
    public void setAutoReload(boolean autoReload) {
        this.autoReload = autoReload;
    }

}
